<template>
    <div>
        <h1>这是孙子组件</h1>
        <h2>{{ info }}</h2>
        <button>点击 切换info内容</button>
    </div>
</template>

<script lang="ts">
import { defineComponent, inject, Ref } from 'vue'

export default defineComponent({
    setup() {

        //总结：
        //inject() 通过 小括号内的标识，与provide()建立连接
        //inject() 接收到值得数据类型：  传过来的是什么数据类型，他就显示什么数据类型，但是他本质上是默认的 unknown 类型
        //inject() 接收到的值的使用：  在template模板中，直接使用。  在setup函数中使用，则要注意数据类型处理
        //           通过provide传过来的值， 基本数据类型通过ref定义数据类型，引用数据类型通过 接口 来定义数据类型
        //          通过provide传过来的值,是 ref 对象，则 通过 泛型 使用Ref定义数据类型;传过来的值是proxy对象，则通过泛型 使用接口进行类型声明
        //           父级组件传递给自己组件的值，能改但不建议更改。
        inject('info')//传过来的值   ref对象（因为他将一个ref对象传过来了，所以他的数据类型显示是ref对象，但是本质上不是，他是unknown）
        console.log(inject('info'))//RefImpl 对象

        //想要在setup函数中拿传过来的具体值，就要进行数据类型处理
        //因为是 ref 对象，则 通过 泛型 使用Ref定义数据类型
        let info = inject<Ref<string>>('info') //Ref是传过来数据的整个一个类型声明(变量info的类型声明)，string是info具体值 的一个类型声明(info?.value的类型声明)

        //这里的 info 显示的是 RefImpl 对象，在template模板中，直接使用，但是在setup函数中，想要获得具体的值
        //因为是ref对象，所以想通过xx.value的方式获得，但是报错。
        // console.log(info.value) // ts 报错：  Object is of type 'unknown'. --> 对象的类型为 unknown
        //说明 虽然inject('xx')显示的是ref对象，但是实质上他是unknown数据类型。
        //所以要进行数据类型处理
        // let info = inject<Ref<string>>('info')
        //等 通过泛型  处理好inject('xx')的数据类型为ref对象时，接着输出
        // console.log(info.value)//报错 Object is possibly 'undefined'.  对象可能“未定义”   代表该对象可有可无，所以用 ?
        console.log(info?.value)// -->今天天气好晴朗！


        //inject 接收数字
        inject('num');
        //关键在于 inject('xx') 显示的是ref对象，但是它实质上是默认的unknown数据类型 ， 所以要通过泛型做数据处理
        let num = inject<Ref<number>>('num')
        console.log(num?.value)// 0 拿到具体的值


        //inject 接收对象
        // let obj = inject('obj')
        // console.log(obj)// proxy 对象
        // console.log(obj.name)//Object is of type 'unknown'.  也就是说虽然显示的proxy对象，但是实质上是unknown数据，要做数据处理
        //传递的是对象数据类型，就要通过泛型 使用接口来进行定义
        interface inObj {
            name: string;
            age: number;
        }
        let obj = inject<inObj>('obj')
        console.log(obj)
        // console.log(obj.name) //报错  Object is possibly 'undefined'.  对象可能未定义，代表对象可有可无
        console.log(obj?.name)

        return {
            info,

        }
    },

})
</script>

<style scoped>

</style>